"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : 15、多窗口处理与网页frame.py
"""

import time
from selenium import webdriver
from selenium.webdriver.common.by import By

# ================================   重点  ============================================
"""
selenium 如何处理多窗口场景：
点击某些链接，会重新打开一个窗口 -> 获取窗口的唯一标识用句柄表示：只需要切换句柄就可以对多个窗口切换
    多个窗口识别
    多个窗口之前切换
selenium 如何处理 frame
    多个 frame 识别
    多个 frame 之前切换

"""


# 获取当前句柄：driver.current_window_handle
# 获取所有句柄：driver.window_handles
# 切换窗口句柄：driver.switch_to_window

# ==================  driver.switch_to.window : 切换窗口（句柄） =====================================
# ==============  判断是否是想要的操作窗口，如果是，就可以对窗口进行操作。如果不是，跳转到另外一个窗口，对另一个窗口进行操作 ==================
def test_myswitch():
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)
    driver.maximize_window()
    driver.get('https://www.baidu.com')
    new_handle = driver.current_window_handle
    # 点击百度按钮
    driver.find_element(By.CSS_SELECTOR, "#s-top-loginbtn").click()
    # 点击百度注册按钮
    driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__regLink").click()
    # 切换百度界面
    handles = driver.window_handles
    for i in handles:
        if i != new_handle:
            driver.switch_to.window(i)
            time.sleep(5)
    driver.switch_to.window(new_handle)


class Testwindow:
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

    def teardown(self):
        self.driver.quit()

    def test_switch_to_handle(self):
        self.driver.get('https://www.baidu.com')
        # 点击百度：登录按钮
        self.driver.find_element(By.CSS_SELECTOR, "#s-top-loginbtn").click()
        # 获取当前窗口句柄  结果为：CDwindow-7ED0B5323325CA17C10CCE65712F1323
        print(self.driver.current_window_handle)

        # 点击百度的立即注册按钮
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__regLink").click()

        # 切换到立即注册页面
        self.driver.switch_to.window(self.driver.window_handles[-1])
        assert self.driver.title == "注册百度帐号"

        # 切换窗口后。获取当前窗口  结果为：CDwindow-EFEAA842D4A1914CAD8CEF4B4288DB9A
        print(self.driver.current_window_handle)
        # 获取当前所有窗口的句柄   结果为：['CDwindow-7ED0B5323325CA17C10CCE65712F1323', 'CDwindow-EFEAA842D4A1914CAD8CEF4B4288DB9A']
        print(self.driver.window_handles)

        # 在立即注册页面上操作
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_4__userName").send_keys('username')
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_4__phone").send_keys('18788888888')

        # 切回到百度页面
        self.driver.switch_to.window(self.driver.window_handles[0])
        time.sleep(5)
        assert self.driver.title == '百度一下，你就知道'

        # 在百度界面：用户名和密码登录
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__userName").send_keys('username')
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__password").send_keys('18788888888')
        self.driver.find_element(By.CSS_SELECTOR, "#TANGRAM__PSP_11__submit").click()
        time.sleep(5)


# ==================  driver.switch_to.frame : 切换 frame =====================================
"""
在 web 自动化中，如果一个元素定位不到，很大可能是在 iframe 中
什么是 frame 
    frame 是 html 中的框架，在 html 中，所谓框架就是可以在一个浏览器中不止一个页面
    基于 html 的框架，又分为 垂直框架 和 水平框架 
Frame 分类：
    frame 标签包含 frameset frame iframe
    frameset 和普通 的标签一样，不会影响正常定位，可以使用 index id name webelement 任意方式定位 frame
    而 frame 与 iframe 对 selenium 定位而言是一样的，selenium 有一组方法对 frame 进行定位
演示环境：
    w3school.com.cn/tiy/t.asp?f=html_frame_cols
"""

# frame：框架：在同一个浏览器中，显示不只一个页面
# 分为垂直框架 和 水平框架


"""
多 frame 切换
    frame 存在两种情况：一种是嵌套的，一种是未嵌套的
切换 frame：
    driver.switch_to.frame('frame的元素id')   根据元素id 或者 index 切换frame
    driver.switch_to.default_content   切换到默认的frame
    driver.switch_to.parent_frame()   切换到父级frame
嵌套的frame -  注意：操作完成需要切回原来的 frame
    对于嵌套的 frame ，先进入 iframe 的父节点，再进入子节点，然后对子节点里面的对象进行处理和操作。再切换到父节点
    先找到frame的父节点：driver.switch_to.frame("frame的父节点")
    在找到子节点： driver.switch_to.frame("frame的子节点") 
    操作完成后，再切换回父节点 ： driver.switch_to.frame("frame的父节点")   
未嵌套的iframe
    driver.switch_to.frame("frame的id")
    driver.switch_to.frame("frame的索引值") - 索引从0开始  或者  driver.switch_to.frame(0)
"""


class Testframe:
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

    def teardown(self):
        self.driver.quit()

    def test_switch_frame(self):
        self.driver.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
        # 切换frame  根据 frame 的元素id
        self.driver.switch_to.frame('iframeResult')
        web_element = self.driver.find_element(By.CSS_SELECTOR, "#draggable")
        print(web_element)
        # 打印元素的属性：结果为 请拖拽我！
        print(self.driver.find_element(By.CSS_SELECTOR, "#draggable").text)

        # 切回父节点的frame框架
        # self.driver.switch_to.parent_frame()
        # 或者使用：切回默认的 frame 框架
        self.driver.switch_to.default_content()

        # 打印原来界面的元素属性   结果为： 点击运行 》
        print(self.driver.find_element(By.CSS_SELECTOR, "#submitBTN").text)

